Skip to content

Update application REST APIs and fix multiple bugs#2234

Merged
lasanthaS merged 11 commits into
wso2:mainfrom
Piumal1999:idp-new
Jun 22, 2026
Merged

Update application REST APIs and fix multiple bugs#2234
lasanthaS merged 11 commits into
wso2:mainfrom
Piumal1999:idp-new

Conversation

@Piumal1999

Copy link
Copy Markdown
Contributor

Purpose

Correcting the application related rest APIs
Updating docs
Fixing multiple authentication related bugs

Approach

  • Changed /applications endpoints to have o/{orgId} prefix similar to other APIs
  • Added validations to cross check the organization in the path and the session/token
  • Added an endpoint to list the applications
  • Updated the docs

@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Piumal1999, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 46 minutes and 19 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6c92ec97-b42c-4384-a2f4-f02e4d515868

📥 Commits

Reviewing files that changed from the base of the PR and between 596fae4 and eff4eef.

📒 Files selected for processing (4)
  • portals/developer-portal/CLAUDE.md
  • portals/developer-portal/src/defaultContent/layout/main.hbs
  • portals/developer-portal/src/routes/pages/orgContentRoute.js
  • portals/developer-portal/src/utils/util.js
📝 Walkthrough

Walkthrough

The pull request transforms the Developer Portal API to enforce explicit organization scoping, requiring all application and key-management operations to include an orgId path segment (/o/{orgId}/devportal/v1/...). Auth middleware gains a new checkOrgIsolation function that validates the request-path org against token or session org claims using organization data lookups. JWT verification is hardened with issuer and audience options across tokenUtil.js, ensureAuthenticated.js, and bearer-token resolution. Session lifecycle handling in authController.js is made more robust through sequential validation, proper session destruction callbacks, and error logging. A new listApplications controller endpoint is introduced, and existing CRUD handlers are refactored to derive org and user identity directly from request parameters instead of database lookups. The config.yaml.example updates orgIDClaim to org_name and clarifies that dp:* scopes apply to machine API clients but not browser sessions. Comprehensive Asgardeo IDP setup and bearer-token curl-based authentication guides are added. All frontend scripts and templates are updated to use the new org-scoped API endpoints.

Suggested reviewers

  • RakhithaRR
  • Tharsanan1
  • VirajSalaka
  • renuka-fernando
  • malinthaprasan
  • AnuGayan
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the Purpose, Approach, and high-level Goals; however, it lacks several required sections such as User stories, Documentation, Automation tests, Security checks, Samples, Related PRs, and Test environment. Add missing sections: User stories, Documentation links, test coverage details (Unit and Integration tests), security checks confirmation, samples information, related PRs, and test environment specifications.
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the primary change—updating application REST APIs and addressing authentication bugs—making it specific and relevant to the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
portals/developer-portal/src/controllers/authController.js (2)

224-230: ⚡ Quick win

Misleading await on callback-based API.

req.session.save(callback) uses callback style and does not return a Promise. The await resolves immediately to undefined rather than waiting for the save to complete. The code works correctly because all logic is inside the callback, but the await is misleading and could confuse future maintainers.

Suggested fix
     req.session.returnTo = req.originalUrl;
     req.session.silentAuthRedirected = true;
-    await req.session.save((err) => {
+    req.session.save((err) => {
         if (err) {
             logger.error('Session save failed during silent SSO', { error: err.message });
             return next();
         }
         passport.authenticate('oauth2', { prompt: 'none' })(req, res, next);
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@portals/developer-portal/src/controllers/authController.js` around lines 224
- 230, The await keyword on the callback-based req.session.save() call is
misleading because this API does not return a Promise, so await resolves
immediately to undefined rather than waiting for the callback to complete.
Remove the await keyword from the req.session.save invocation in the silent SSO
authentication handler, as the callback pattern already properly handles the
asynchronous flow and all logic is correctly contained within the callback.

163-170: 💤 Low value

Redundant header assignment.

Cache-Control is already set at line 151 before entering the conditional branches. This duplicate set on line 167 is unnecessary.

Suggested fix
             req.session.destroy((destroyErr) => {
                 if (destroyErr) {
                     logger.error('Session destroy failed on local-auth logout', { error: destroyErr.message });
                 }
-                res.set('Cache-Control', 'no-store');
                 res.redirect(req.originalUrl.replace('/logout', '/login'));
             });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@portals/developer-portal/src/controllers/authController.js` around lines 163
- 170, The Cache-Control header is being set twice in the logout flow: once at
line 151 and again inside the req.session.destroy callback at line 167. Remove
the duplicate res.set('Cache-Control', 'no-store'); statement from inside the
session destroy callback since the header is already configured earlier in the
control flow before entering the conditional branches.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@portals/developer-portal/src/controllers/devportalController.js`:
- Line 165: Fix the typo in the delete success response message in
devportalController.js where "Resouce" is misspelled and should be "Resource".
Update the response text in the res.status(200).send() call to correctly spell
"Resource Deleted Successfully" instead of "Resouce Deleted Successfully". This
typo appears in multiple locations (at lines 165 and 175), so make sure to
correct all occurrences throughout the file.
- Line 75: The request parameters being logged directly in error messages (such
as orgId in req.params.orgId) need to be normalized to remove CR/LF characters
before being attached to log metadata. Extract and normalize the route
parameters (req.params.orgId and any other request-path values) by removing
carriage returns and line feeds early in the request handler, then use these
sanitized values in all subsequent logger.error calls that reference them. This
normalization should be applied consistently across the error logging statements
at lines 75, 90, 109, and 178 to ensure logs remain safe and reliable for
downstream processing.

In `@portals/developer-portal/src/middlewares/authMiddleware.js`:
- Around line 96-131: The checkOrgIsolation function currently treats all errors
from orgDao.get() as internal server errors, but the upstream contract indicates
that a missing organization throws Sequelize.EmptyResultError rather than
returning a falsy value, making the !orgDetails check unreachable. Modify the
catch block that handles the orgDao.get() call to distinguish between
Sequelize.EmptyResultError (which should return a 404 status) and other errors
(which should return 500 status). This will ensure that missing organizations
are properly reported as 404 Not Found instead of 500 Internal Server Error, and
you can remove the now-reachable !orgDetails check.

---

Nitpick comments:
In `@portals/developer-portal/src/controllers/authController.js`:
- Around line 224-230: The await keyword on the callback-based
req.session.save() call is misleading because this API does not return a
Promise, so await resolves immediately to undefined rather than waiting for the
callback to complete. Remove the await keyword from the req.session.save
invocation in the silent SSO authentication handler, as the callback pattern
already properly handles the asynchronous flow and all logic is correctly
contained within the callback.
- Around line 163-170: The Cache-Control header is being set twice in the logout
flow: once at line 151 and again inside the req.session.destroy callback at line
167. Remove the duplicate res.set('Cache-Control', 'no-store'); statement from
inside the session destroy callback since the header is already configured
earlier in the control flow before entering the conditional branches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d72555f5-946a-4ca6-b073-a5c622fb9b1b

📥 Commits

Reviewing files that changed from the base of the PR and between 01d2cb2 and b3af367.

📒 Files selected for processing (15)
  • docs/rest-apis/devportal/README.md
  • docs/rest-apis/devportal/application-keys.md
  • docs/rest-apis/devportal/applications.md
  • portals/developer-portal/configs/config.yaml.example
  • portals/developer-portal/docs/README.md
  • portals/developer-portal/docs/administer/api-token-curl.md
  • portals/developer-portal/docs/administer/asgardeo-setup.md
  • portals/developer-portal/docs/devportal-openapi-spec-v1.yaml
  • portals/developer-portal/src/controllers/authController.js
  • portals/developer-portal/src/controllers/devportalController.js
  • portals/developer-portal/src/middlewares/authMiddleware.js
  • portals/developer-portal/src/middlewares/ensureAuthenticated.js
  • portals/developer-portal/src/middlewares/passportConfig.js
  • portals/developer-portal/src/routes/api/handlers/applicationsHandler.js
  • portals/developer-portal/src/utils/tokenUtil.js

Comment thread portals/developer-portal/src/controllers/devportalController.js Outdated
Comment thread portals/developer-portal/src/controllers/devportalController.js Outdated
Comment thread portals/developer-portal/src/middlewares/authMiddleware.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@portals/developer-portal/src/services/apiFlowService.js`:
- Around line 186-192: Move the orgDao.get(orgID) call and
sequelize.transaction() creation from before the try block into inside the try
block so that failures in these operations are caught by the existing catch
handler. Additionally, update the catch block to only perform transaction
rollback when the transaction variable t was successfully created, by checking
if t exists before calling rollback.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4aa8be90-e794-4a29-ab76-06fe626b0f8f

📥 Commits

Reviewing files that changed from the base of the PR and between b3af367 and 66c2080.

📒 Files selected for processing (13)
  • portals/developer-portal/src/controllers/applicationsContentController.js
  • portals/developer-portal/src/controllers/authController.js
  • portals/developer-portal/src/controllers/devportalController.js
  • portals/developer-portal/src/defaultContent/layout/main.hbs
  • portals/developer-portal/src/middlewares/authMiddleware.js
  • portals/developer-portal/src/middlewares/ensureAuthenticated.js
  • portals/developer-portal/src/scripts/add-application-form.js
  • portals/developer-portal/src/scripts/common.js
  • portals/developer-portal/src/scripts/edit-application-form.js
  • portals/developer-portal/src/scripts/oauth2-key-generation.js
  • portals/developer-portal/src/scripts/warning.js
  • portals/developer-portal/src/services/apiFlowService.js
  • portals/developer-portal/src/services/apiMetadataService.js
💤 Files with no reviewable changes (1)
  • portals/developer-portal/src/services/apiMetadataService.js
🚧 Files skipped from review as they are similar to previous changes (4)
  • portals/developer-portal/src/middlewares/authMiddleware.js
  • portals/developer-portal/src/controllers/devportalController.js
  • portals/developer-portal/src/middlewares/ensureAuthenticated.js
  • portals/developer-portal/src/controllers/authController.js

Comment thread portals/developer-portal/src/services/apiFlowService.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/rest-apis/devportal/applications.md (1)

363-363: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update Delete operation description for consistency with other operations.

The Delete operation description omits reference to organization scoping, unlike the List, Create, and Update operations. Since the endpoint requires orgId as a path parameter, the description should clarify that deletion occurs within the specified organization.

Suggested change: "Deletes an application owned by the authenticated user in the specified organization."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/rest-apis/devportal/applications.md` at line 363, The Delete operation
description for applications at line 363 omits reference to organization
scoping, which is inconsistent with the List, Create, and Update operations that
all include organization context. Update the Delete operation description to
clarify that the deletion occurs within the specified organization. Add "in the
specified organization" or similar phrasing to match the organization scoping
pattern used in the other operation descriptions, since the endpoint requires
orgId as a path parameter.
🧹 Nitpick comments (1)
portals/developer-portal/src/dao/applicationDao.js (1)

57-61: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider adding null guard for the findOne result.

If the record is deleted between the successful update and the subsequent findOne, updatedApp will be null. The controller accesses updatedApp[0].dataValues, which would throw an error in this unlikely scenario.

Additionally, for consistency with the get function (line 77) and the update WHERE clause itself, consider including CREATED_BY: userID in the findOne query.

Suggested change
         if (!updatedRowsCount) {
             return [updatedRowsCount, null];
         }
-        const updatedApp = await Application.findOne({ where: { ORG_ID: orgID, APP_ID: appID } });
+        const updatedApp = await Application.findOne({ where: { ORG_ID: orgID, APP_ID: appID, CREATED_BY: userID } });
+        if (!updatedApp) {
+            return [updatedRowsCount, null];
+        }
         return [updatedRowsCount, [updatedApp]];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@portals/developer-portal/src/dao/applicationDao.js` around lines 57 - 61, Add
a null guard after the Application.findOne call in the update function to handle
the edge case where the record might be deleted between the successful update
and the subsequent query. Check if updatedApp is null and return an appropriate
response (such as null or an error indicator) to prevent the controller from
accessing updatedApp[0].dataValues on a null value. Additionally, include
CREATED_BY: userID in the findOne WHERE clause alongside ORG_ID and APP_ID to
maintain consistency with the get function and the WHERE clause used in the
update operation itself.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@docs/rest-apis/devportal/applications.md`:
- Line 363: The Delete operation description for applications at line 363 omits
reference to organization scoping, which is inconsistent with the List, Create,
and Update operations that all include organization context. Update the Delete
operation description to clarify that the deletion occurs within the specified
organization. Add "in the specified organization" or similar phrasing to match
the organization scoping pattern used in the other operation descriptions, since
the endpoint requires orgId as a path parameter.

---

Nitpick comments:
In `@portals/developer-portal/src/dao/applicationDao.js`:
- Around line 57-61: Add a null guard after the Application.findOne call in the
update function to handle the edge case where the record might be deleted
between the successful update and the subsequent query. Check if updatedApp is
null and return an appropriate response (such as null or an error indicator) to
prevent the controller from accessing updatedApp[0].dataValues on a null value.
Additionally, include CREATED_BY: userID in the findOne WHERE clause alongside
ORG_ID and APP_ID to maintain consistency with the get function and the WHERE
clause used in the update operation itself.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3bce2ed5-1171-4a0c-b347-ef52fc3d49dc

📥 Commits

Reviewing files that changed from the base of the PR and between 9f6eee2 and 596fae4.

📒 Files selected for processing (27)
  • docs/rest-apis/devportal/README.md
  • docs/rest-apis/devportal/application-keys.md
  • docs/rest-apis/devportal/applications.md
  • portals/developer-portal/configs/config.yaml.example
  • portals/developer-portal/docs/README.md
  • portals/developer-portal/docs/administer/api-token-curl.md
  • portals/developer-portal/docs/administer/asgardeo-setup.md
  • portals/developer-portal/docs/devportal-openapi-spec-v1.yaml
  • portals/developer-portal/src/controllers/applicationsContentController.js
  • portals/developer-portal/src/controllers/authController.js
  • portals/developer-portal/src/controllers/devportalController.js
  • portals/developer-portal/src/dao/applicationDao.js
  • portals/developer-portal/src/defaultContent/layout/main.hbs
  • portals/developer-portal/src/middlewares/authMiddleware.js
  • portals/developer-portal/src/middlewares/ensureAuthenticated.js
  • portals/developer-portal/src/middlewares/passportConfig.js
  • portals/developer-portal/src/pages/applications/partials/applications-listing.hbs
  • portals/developer-portal/src/routes/api/handlers/applicationsHandler.js
  • portals/developer-portal/src/scripts/add-application-form.js
  • portals/developer-portal/src/scripts/common.js
  • portals/developer-portal/src/scripts/edit-application-form.js
  • portals/developer-portal/src/scripts/oauth2-key-generation.js
  • portals/developer-portal/src/scripts/warning.js
  • portals/developer-portal/src/services/apiFlowService.js
  • portals/developer-portal/src/services/apiMetadataService.js
  • portals/developer-portal/src/styles/applications.css
  • portals/developer-portal/src/utils/tokenUtil.js
✅ Files skipped from review due to trivial changes (7)
  • portals/developer-portal/docs/README.md
  • docs/rest-apis/devportal/README.md
  • portals/developer-portal/src/styles/applications.css
  • portals/developer-portal/src/services/apiMetadataService.js
  • portals/developer-portal/src/controllers/applicationsContentController.js
  • portals/developer-portal/docs/administer/api-token-curl.md
  • docs/rest-apis/devportal/application-keys.md
🚧 Files skipped from review as they are similar to previous changes (16)
  • portals/developer-portal/src/defaultContent/layout/main.hbs
  • portals/developer-portal/src/routes/api/handlers/applicationsHandler.js
  • portals/developer-portal/src/middlewares/passportConfig.js
  • portals/developer-portal/src/scripts/add-application-form.js
  • portals/developer-portal/src/scripts/common.js
  • portals/developer-portal/src/scripts/warning.js
  • portals/developer-portal/src/scripts/edit-application-form.js
  • portals/developer-portal/configs/config.yaml.example
  • portals/developer-portal/src/utils/tokenUtil.js
  • portals/developer-portal/src/services/apiFlowService.js
  • portals/developer-portal/docs/administer/asgardeo-setup.md
  • portals/developer-portal/src/controllers/devportalController.js
  • portals/developer-portal/src/controllers/authController.js
  • portals/developer-portal/docs/devportal-openapi-spec-v1.yaml
  • portals/developer-portal/src/middlewares/authMiddleware.js
  • portals/developer-portal/src/middlewares/ensureAuthenticated.js

@lasanthaS lasanthaS merged commit 492207c into wso2:main Jun 22, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants